package com.szxy.miaosha.conf;

import com.szxy.miaosha.domain.MiaoshaUser;
import com.szxy.miaosha.service.MiaoShaUserService;
import com.szxy.miaosha.utils.Constant;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author: zwz
 * @Date:2020/9/7 22:38
 * @Description:com.szxy.miaosha.conf
 * @Version:1.0
 **/
@Component
public class MiaoShaUserArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    private MiaoShaUserService miaoShaUserService;

    /**
     * 只针对 MiaoshaUser 参数做处理
     *
     * @param methodParameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        Class<?> clazz = methodParameter.getParameterType();
        return clazz == MiaoshaUser.class;
    }

    /**
     * 具体处理实现
     *
     * @param methodParameter
     * @param modelAndViewContainer
     * @param nativeWebRequest
     * @param webDataBinderFactory
     * @return
     * @throws Exception
     */
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer
            , NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        // 获取 req 对象 和 resp 对象
        HttpServletRequest req = (HttpServletRequest) nativeWebRequest.getNativeRequest();
        HttpServletResponse resp = (HttpServletResponse) nativeWebRequest.getNativeResponse();
        // 获取参数值
        String paramToken = req.getParameter(Constant.COOKIES_TOKEN_KEY);
        String cookieToken = getTokenByCookies(req, Constant.COOKIES_TOKEN_KEY);
        // paramToken 优先级高于 cookieToken
        String token = paramToken != null ? paramToken : cookieToken;
        return miaoShaUserService.getByToken(resp, token);
    }

    /**
     * 从请求信息中获取 token
     *
     * @param req
     * @param cookiesTokenKey
     * @return
     */
    private String getTokenByCookies(HttpServletRequest req, String cookiesTokenKey) {
        // 获取 cookies
        Cookie[] cookies = req.getCookies();
        if (cookies == null || cookies.length < 0) {
            return null;
        }
        for (Cookie cookie : cookies) {
            String name = cookie.getName();
            if (!StringUtils.isEmpty(name) && Constant.COOKIES_TOKEN_KEY.equals(name)) {
                return cookie.getValue();
            }
        }
        return null;
    }
}
